﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Collections.ObjectModel;
using System.Xml.XPath;
using System.IO;
//using System.Xml;

namespace DbSharp.Framework.CaseFile
{
    /// <summary>
    /// Test case file navigatation class
    /// </summary>
    public class CaseFileNavigator
    {
        #region Private members

        private XDocument m_Xdoc;
        private string m_TestCaseFileName;
        #endregion

      
        public CaseFileNavigator(string testCaseFileName)
        {
            m_TestCaseFileName = testCaseFileName;
            m_Xdoc = XDocument.Load(m_TestCaseFileName);
        }

        #region Private methods


  

        private XElement SelectObjectNode(XElement xdoc, string objName, string objXPath, string attributeName)
        {
            if (string.IsNullOrEmpty(objName))
                return null;

            string trimedName = objName.Trim();
            string xPath = objXPath;
            var elmts = xdoc.XPathSelectElements(xPath);
            foreach (var item in elmts)
            {
                string name2 = item.Attribute(attributeName).Value.Trim();
                if (string.Equals(trimedName, name2, StringComparison.Ordinal))
                    return item;
            }
            return null;
        }

        private XElement SelectObjectNodeInMainFile(string objName, string objXPath, string attributeName)
        {
            return SelectObjectNode(m_Xdoc.Root, objName, objXPath, attributeName);
        }


        private XElement SelectObjectNodeInExternalFile(string externalFileName, string objName, string objXPath, string attributeName)
        {
            if (File.Exists(externalFileName))
            {
                var root = XDocument.Load(externalFileName).Root;
                return SelectObjectNode(root, objName, objXPath, attributeName);
            }
            else
                return null;
        }

        private string GetExternalDbCfgFile()
        {
            var m_XGlobalSettingElement = SelectGlobalSetting();
            var externalDbFileAttr = m_XGlobalSettingElement.Attribute("dbConnectionFile");
            if (externalDbFileAttr != null)
            {
                string externalDbFile = externalDbFileAttr.Value.Trim();
                string absolutePath = Path.GetFullPath(m_TestCaseFileName);
                absolutePath = Path.GetDirectoryName(absolutePath);
                externalDbFile = Path.Combine(absolutePath, externalDbFile);
                return externalDbFile;
            }
            else
                return string.Empty;
        }
        

        #endregion


        #region Public methods/properties

        public string ExternalDbCfgFile
        {
            get { return GetExternalDbCfgFile(); }
        }





        public XElement SelectRootElement()
        {
            return m_Xdoc.Root;
        }


        public XElement SelectGlobalSetting()
        {
            return m_Xdoc.Element("dbTestFixture").Element("globalSetting");
        }



        public XElement SelectProcDeclsRoot()
        {
            return m_Xdoc.Element("dbTestFixture").Element("procDeclarations");
        }



        public XElement SelectSqlDeclsRoot()
        {
            return m_Xdoc.Element("dbTestFixture").Element("sqlDeclarations");
        }



        public XElement SelectPerfTestCasesRoot()
        {
            return m_Xdoc.Element("dbTestFixture").Element("perfTestCases");
        }



        public XElement SelectDataTestCasesRoot()
        {
            return m_Xdoc.Element("dbTestFixture").Element("unitTestCases");
        }



        public XElement SelectDbConn(string connectionName)
        {
            string xPath = "//dbConnection";
            string attributeName="connectionName";
            XElement result = SelectObjectNodeInMainFile(connectionName, xPath, attributeName);

            //get DbConnection from external file
            if (result==null)
            {
                string externalFile=this.GetExternalDbCfgFile() ;
                if (File.Exists(externalFile))
                {
                    result=SelectObjectNodeInExternalFile(externalFile, connectionName, xPath, attributeName);
                }
            }
            return result;
        }

    

        public XElement SelectPerfTestCase(string testCaseName)
        {
            string xPath = "//perfTestCase";
            string attributeName = "testCaseName";
            return SelectObjectNodeInMainFile(testCaseName, xPath, attributeName);
        }
   
      


        public XElement SelectUnitTestCase(string testCaseName)
        {
            string xPath = "//unitTestCase";
            string attributeName = "testCaseName";
            return SelectObjectNodeInMainFile(testCaseName, xPath, attributeName);
        }

 
         

        public XElement SelectSqlDeclaration(string aliasValue)
        {
            string xPath = "//sqlDeclaration";
            string attributeName = "alias";
            return SelectObjectNodeInMainFile(aliasValue, xPath, attributeName);
        }

     

        public XElement SelectProcedureDeclaration(string aliasValue)
        {
            string xPath = "//procDeclaration";
            string attributeName = "alias";
            return SelectObjectNodeInMainFile(aliasValue, xPath, attributeName);
        }
         
         
        #endregion
    }
}